package com.kaige.asktaoplugin60.plugin;

import com.kaige.asktaoplugin60.config.GameConfig;
import com.kaige.asktaoplugin60.config.PluginConfig;
import com.kaige.asktaoplugin60.handler.PluginServerHandler;
import com.kaige.asktaoplugin60.utils.ServerUtil;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 游戏代理服务类
 * 负责启动Netty服务器，处理客户端与服务端之间的消息转发
 */
@Slf4j
@Component
public class Plugin {

    @Autowired
    private GameConfig gameConfig;
    
    @Autowired
    private PluginConfig pluginConfig;

    // Netty线程组
    private NioEventLoopGroup bossGroup;
    private NioEventLoopGroup workerGroup;

    // 服务器通道Future
    private ChannelFuture serverChannelFuture;
    
    // 线路服务器通道Futures
    private List<ChannelFuture> lineChannelFutures = new ArrayList<>();

    /**
     * 初始化并启动代理服务
     */
    @PostConstruct
    public void startProxy() {
        try {
            log.info("开始启动游戏代理服务...");

            // 初始化线程组
            bossGroup = new NioEventLoopGroup(1);
            workerGroup = new NioEventLoopGroup();

            // 启动主服务端，监听客户端连接
            serverChannelFuture = ServerUtil.startServer(
                    pluginConfig.getPort(), // 代理服务监听端口
                    bossGroup,
                    workerGroup,
                    new PluginServerHandler(gameConfig, pluginConfig)  // 传递gameConfig和pluginConfig给Handler
            );

            log.info("游戏代理服务启动成功，监听端口: {}", pluginConfig.getPort());
            
            // 启动线路服务
            startLineServices();
        } catch (Exception e) {
            log.error("游戏代理服务启动失败", e);
        }
    }
    
    /**
     * 启动线路服务
     */
    private void startLineServices() {
        try {
            Map<String, Integer> pluginLinePorts = pluginConfig.getLine();
            Map<String, Integer> gameLinePorts = gameConfig.getLine();
            
            if (pluginLinePorts != null && gameLinePorts != null) {
                for (Map.Entry<String, Integer> entry : pluginLinePorts.entrySet()) {
                    String lineName = entry.getKey();
                    Integer pluginPort = entry.getValue();
                    Integer gamePort = gameLinePorts.get(lineName);
                    
                    if (gamePort != null) {
                        // 为每个线路创建一个新的Handler实例
                        PluginServerHandler lineHandler = new PluginServerHandler(gameConfig, pluginConfig);
                        lineHandler.setLinePort(gamePort); // 设置线路端口
                        
                        ChannelFuture lineChannelFuture = ServerUtil.startServer(
                                pluginPort,
                                bossGroup,
                                workerGroup,
                                lineHandler
                        );
                        
                        lineChannelFutures.add(lineChannelFuture);
                        log.info("线路服务启动成功，线路: {}, 监听端口: {} -> 目标端口: {}", 
                                lineName, pluginPort, gamePort);
                    } else {
                        log.warn("未找到线路 {} 对应的游戏服务端口", lineName);
                    }
                }
            } else {
                log.info("未配置线路服务");
            }
        } catch (Exception e) {
            log.error("线路服务启动失败", e);
        }
    }

    /**
     * 关闭代理服务
     */
    @PreDestroy
    public void stopProxy() {
        log.info("正在关闭游戏代理服务...");

        if (serverChannelFuture != null) {
            serverChannelFuture.channel().close();
        }
        
        // 关闭线路服务
        for (ChannelFuture lineChannelFuture : lineChannelFutures) {
            if (lineChannelFuture != null) {
                lineChannelFuture.channel().close();
            }
        }

        if (bossGroup != null) {
            bossGroup.shutdownGracefully();
        }

        if (workerGroup != null) {
            workerGroup.shutdownGracefully();
        }

        log.info("游戏代理服务已关闭");
    }

}